package org.qy.hbase.server.utils;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;
import org.qy.hbase.server.api.Property;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author HeQixuan
 * @date 2019-11-23
 * 实体对象映射辅助工具类
 */
public class RowMapperUtils {

    private static Logger logger = LoggerFactory.getLogger(RowMapperUtils.class);

    /**
     * 列族名
     */
    public static final String DEFAULT_FAMILY = "DATA";

    /**
     * 设置值
     * @param cls 实体类型
     * @param result 结果集
     * @return
     */
    public static Object setRowValue(Class cls, Result result){
        Object t = null;
        try {
            t = cls.newInstance();
            //设置类属性值
            setValue(cls, t, result);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return t;
    }

    /**
     * 递归设置属性值
     * @param cls
     * @param t
     * @param result
     */
    private static void setValue(Class cls, Object t, Result result){
        final Class superclass = cls.getSuperclass();
        if(superclass != null){
            setValue(superclass, t, result);
        }
        final Field[] declaredFields = cls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            final String name = declaredField.getName();
            if("serialVersionUID".equals(declaredField.getName())){
                continue;
            }
            try {
                String columnName;

                Property property = declaredField.getAnnotation(Property.class);
                if(property==null){
                    columnName =ColumnUtils.camelToUnderline(name);
                }else{
                    columnName = property.name();
                }
                byte[] bytesValue = result.getValue(Bytes.toBytes(DEFAULT_FAMILY), columnName.getBytes());
                if(StringUtils.equals("id", name)){
                    bytesValue = result.getRow();
                }
                if(bytesValue != null && bytesValue.length > 0){
                    //若该属性值存在且有值则将其赋值给实例对象
                    String sName = "set" + StringUtils.capitalize(name);
                    Class<?> type = cls.getDeclaredField(name).getType();
                    Method declaredMethod = cls.getDeclaredMethod(sName, type);
                    declaredMethod.invoke(t, ColumnUtils.getValue(bytesValue, type));
                }
            } catch (Exception e) {
                logger.error("fieldName is " + name + ", detailMessage: " +e.getMessage(), e);
            }
        }
    }
}
